
package com.chuanke.ckfamily.service.social.impl;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

import com.chuanke.ckfamily.service.user.FriendApplyService;
import com.chuanke.ckfamily.service.user.UserRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.weijie.core.BaseBiz;
import com.chuanke.ckfamily.dao.social.SpecialRelationDao;
import com.chuanke.ckfamily.dao.social.model.SpecialRelation;
import com.chuanke.ckfamily.dao.user.model.User;
import com.chuanke.ckfamily.service.base.FailCode;
import com.chuanke.ckfamily.service.common.CacheService;
import com.chuanke.ckfamily.service.common.WyService;
import com.chuanke.ckfamily.service.common.impl.RedisLockUtil;
import com.chuanke.ckfamily.service.constant.SpecialRelationConstant;
import com.chuanke.ckfamily.service.exception.CFException;
import com.chuanke.ckfamily.service.social.SpecialRelationService;
import com.chuanke.ckfamily.service.user.UserService;

@Service
@Transactional(rollbackFor = Exception.class)
public class SpecialRelationServiceImpl extends BaseBiz<SpecialRelation, SpecialRelationDao> implements SpecialRelationService {

	@Autowired
	private UserService userService;

	@Autowired
	private UserRelationService userRelationService;

	@Autowired
	private WyService wyService;

	@Autowired
	private CacheService cacheService;

	@Override
	public SpecialRelation findSpecialRelation(Long user_id, Long target_user_id, int relation_type) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_id", user_id);
		param.put("target_user_id", target_user_id);
		param.put("relation_type", relation_type);
		return baseDao.findSpecialRelation(param);
	}

	@Override
	public boolean isMute(Long user_id, Long target_user_id) {
		SpecialRelation relation = this.findSpecialRelation(user_id, target_user_id, SpecialRelationConstant.relation_type_mute);
		return relation != null && relation.getValue() == SpecialRelationConstant.relation_value_blackMute;
	}

	@Override
	public boolean isBlack(Long user_id, Long target_user_id) {
		SpecialRelation relation = this.findSpecialRelation(user_id, target_user_id, SpecialRelationConstant.relation_type_black);
		return relation != null && relation.getValue() == SpecialRelationConstant.relation_value_blackMute;
	}

	@Override
	public boolean mute(Long uid, Long tuserId, int value) throws CFException {
		User user = userService.findById(uid);
		if (user == null) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}
		User tuser = userService.findById(tuserId);
		if (tuser == null) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}
		if (value != SpecialRelationConstant.relation_value_blackMute && value != SpecialRelationConstant.relation_value_unBlackMute) {
			throw new CFException(FailCode.PARAMS_ERROR);
		}

		SpecialRelation relation = this.findSpecialRelation(uid, tuserId, SpecialRelationConstant.relation_type_mute);
		if (relation == null) {
			relation = new SpecialRelation();
			relation.setRelation_type(SpecialRelationConstant.relation_type_mute);
			relation.setTarget_user_id(tuserId);
			relation.setUser_id(uid);
			relation.setValue(value);
			relation.setCreate_time(new Timestamp(System.currentTimeMillis()));
			relation.setUpdate_time(new Timestamp(System.currentTimeMillis()));
			this.save(relation);
		} else {
			relation.setUpdate_time(new Timestamp(System.currentTimeMillis()));
			relation.setValue(value);
			this.update(relation);
		}
		wyService.setSpecialRelation(user.getUser_no(), tuser.getUser_no(), SpecialRelationConstant.relation_type_mute, value);
		return true;
	}

	@Override
	public Map<String, Object> black(Long uid, Long tuserId, int value) throws CFException {
		Map<String, Object> result = new HashMap<>();
		User user = userService.findById(uid);
		RedisLockUtil lockUtil = null;
		if (user == null) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}

		User tuser = userService.findById(tuserId);
		if (tuser == null) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}

		if (value != SpecialRelationConstant.relation_value_blackMute && value != SpecialRelationConstant.relation_value_unBlackMute) {
			throw new CFException(FailCode.PARAMS_ERROR);
		}

		try {
			String lock = uid <= tuserId.longValue() ? uid + "_" + tuserId : tuserId + "_" + uid;
			lockUtil = cacheService.getLock(CacheService.KEY_PREFIX.special_relation_.name() + lock);
			if (value == SpecialRelationConstant.relation_value_blackMute) {
				SpecialRelation relation = findSpecialRelation(uid, tuserId, SpecialRelationConstant.relation_type_black);
				if(relation == null){
					addBalckRelation(uid, tuserId, value);
				}
				if (!isBlack(tuserId, uid)) {
					wyService.setSpecialRelation(user.getUser_no(), tuser.getUser_no(), SpecialRelationConstant.relation_type_black, value);
					wyService.setSpecialRelation(tuser.getUser_no(), user.getUser_no(), SpecialRelationConstant.relation_type_black, value);
				}

			} else if (value == SpecialRelationConstant.relation_value_unBlackMute) {
				
				SpecialRelation relation = this.findSpecialRelation(uid, tuserId, SpecialRelationConstant.relation_type_black);
				if (relation != null) {
					delete(relation);
				}
				boolean isBlack = isBlack(tuserId, uid);
				if (!isBlack && userRelationService.isFriend(uid, tuserId)) {
					wyService.setSpecialRelation(user.getUser_no(), tuser.getUser_no(), SpecialRelationConstant.relation_type_black, value);
					wyService.setSpecialRelation(tuser.getUser_no(), user.getUser_no(), SpecialRelationConstant.relation_type_black, value);
				}

			} else {
				throw new CFException(FailCode.APP);

			}
			wyService.updateRelationExpand(user.getUser_no(), tuser.getUser_no());
			result = userService.formatUserBalanceCode(user, tuser, null, null);
			
		} catch (Exception e) {
			e.printStackTrace();
			
		} finally {
			if (lockUtil != null) {
				lockUtil.unlock();
			}
		}
		return result;
	}

	private SpecialRelation addBalckRelation(Long uid, Long tuserId, int value) {
		SpecialRelation relation = this.findSpecialRelation(uid, tuserId, SpecialRelationConstant.relation_type_black);
		if (relation == null) {
			relation = new SpecialRelation();
			relation.setRelation_type(SpecialRelationConstant.relation_type_black);
			relation.setTarget_user_id(tuserId);
			relation.setUser_id(uid);
			relation.setValue(value);
			relation.setCreate_time(new Timestamp(System.currentTimeMillis()));
			relation.setUpdate_time(new Timestamp(System.currentTimeMillis()));
			save(relation);
			return relation;

		} else {
			SpecialRelation update = new SpecialRelation();
			update.setId(relation.getId());
			update.setUpdate_time(new Timestamp(System.currentTimeMillis()));
			update.setValue(value);
			update(update);
			return findById(relation.getId());

		}
	}
}